package com.xc.word.wordUtil;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xc.common.tool.Helper;
import com.xc.db.tables.LibChoice;
import com.xc.db.tables.LibQuestion;
import com.xc.ksxt.entity.*;
import com.xc.ksxt.service.*;
import com.xc.sys.entity.SysDictEntity;
import com.xc.sys.entity.SysUserEntity;
import com.xc.sys.service.BaseCodeNumberService;
import com.xc.sys.service.SysDictService;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.xwpf.usermodel.*;
import org.dom4j.*;
import org.dom4j.Document;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jooq.DSLContext;
import org.jooq.Record1;
import org.jooq.Result;
import org.openxmlformats.schemas.officeDocument.x2006.math.CTBox;
import org.openxmlformats.schemas.officeDocument.x2006.math.CTOMath;
import org.openxmlformats.schemas.officeDocument.x2006.math.CTSSub;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import static org.jooq.impl.DSL.*;

import java.io.*;
import java.math.BigInteger;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;

/**
 * word读取工具类
 * @author Administrator
 *
 */
@Component
public class WordRead {
	@Autowired
	private LibQuestionService libQuestionService;

	@Autowired
	private LibChoiceService libChoiceService;

	@Autowired
	private DSLContext dsl;
	private LibQuestion LIBQUESTIONTB = LibQuestion.LIB_QUESTION.as("LIBQUESTIONTB");

	/**
	 * 获取段落内容（ docx后缀名的Word）
	 * @param paragraph
	 */
	private static String getParagraphText(XWPFParagraph paragraph) {
		// 获取段落中所有内容
		List<XWPFRun> runs = paragraph.getRuns();
		if (runs.size() == 0) {
			//System.out.println("按了回车（新段落）");
			return "";
		}
		StringBuffer runText = new StringBuffer();
		for (XWPFRun run : runs) {
			runText.append(run.text());
		}
//		if (runText.length() > 0) {
//			runText.append("，对齐方式：").append(paragraph.getAlignment().name());
//			System.out.println(runText);
//		}
		return runText.toString();
	}  

	/**
	 * 获取表格内容并组装表格HTML
	 * @param table
	 */
	private static String getTabelHtmlText(XWPFTable table) {
		String result="";
		//获取表格数据行
		List<XWPFTableRow> rows = table.getRows();
	    
		if(rows.size()>0){
			result+="<table border='1' cellspacing=0 style='border-collapse: collapse;'>";
			//遍历
			for (int i=0;i<rows.size();i++) {
				XWPFTableRow row = rows.get(i);
				StringBuffer styleBuf = new StringBuffer();
//				System.out.println(row.getHeight()+"===");
				result+="<tr>";
				//获取每行的数据列
				List<XWPFTableCell> cells = row.getTableCells();
				for (XWPFTableCell cell : cells) {
					//获取单元格跨列个数
					BigInteger gridSpanNum = getCellGridSpanNum(cell);
					
					result+="<td colspan="+gridSpanNum+" valign=center style='text-align: center;vertical-align: middle;'>";
					String cellText="";
					// 简单获取内容（简单方式是不能获取字体对齐方式的）
					// System.out.println(cell.getText());
					// 一个单元格可以理解为一个word文档，单元格里也可以加段落与表格
					List<XWPFParagraph> paragraphs = cell.getParagraphs();
					for (XWPFParagraph paragraph : paragraphs) {
						try{
							cellText += "<p style='margin: unset;text-align:"+paragraph.getAlignment().name()+"'>"+getParagraphText(paragraph)+"</p>";
						}catch (IllegalArgumentException e){
							cellText += "<p style='margin: unset;text-align:center'>"+getParagraphText(paragraph)+"</p>";
						}

					}
					result += cellText;
					result+="</td>";
				}
				
				result+="</tr>";
			}
			result+="</table>";
		}
		return result;
	}
	
	/**
	 * 获取单元格跨列个数
	 * @return
	 */
	public static BigInteger getCellGridSpanNum(XWPFTableCell cell){
		BigInteger gridSpanNum =null;
		//获取单元格跨列
		CTDecimalNumber gridSpanXml = cell.getCTTc().getTcPr().getGridSpan();
		if(gridSpanXml!=null){
			gridSpanNum = gridSpanXml.getVal();
		}
		return gridSpanNum;
	}
	
	/**
	 * 获取单元格跨行
	 * @return
	 */
	public static int getCellVMergeNum(XWPFTableCell cell){
		int vMergeNum =0;
		//获取单元格跨行
		CTVMerge vMergeXml = cell.getCTTc().getTcPr().getVMerge();
		if(vMergeXml!=null){
			System.out.println("vMergeXml:"+vMergeXml);
		}
		return vMergeNum;
	}
	private String getMath(XWPFRun run, Node runNode) throws Exception {
		Node objectNode = getChildNode(runNode, "w:object");
		if (objectNode == null) {
			return "";
		}
		Node shapeNode = getChildNode(objectNode, "v:shape");
		if (shapeNode == null) {
			return "";
		}
		Node imageNode = getChildNode(shapeNode, "v:imagedata");
		if (imageNode == null) {
			return "";
		}
		Node binNode = getChildNode(objectNode, "o:OLEObject");
		if (binNode == null) {
			return "";
		}

		XWPFDocument word = run.getDocument();

		NamedNodeMap shapeAttrs = shapeNode.getAttributes();
		// 图片在Word中显示的宽高
		String style = shapeAttrs.getNamedItem("style").getNodeValue();
		System.out.println("图片宽高：".concat(style));

		System.out.println("--------------");

		NamedNodeMap imageAttrs = imageNode.getAttributes();
		// 图片在Word中的ID
		String imageRid = imageAttrs.getNamedItem("r:id").getNodeValue();
		// 获取图片信息
		PackagePart imgPart = word.getPartById(imageRid);
		System.out.println("图片名称".concat(imgPart.getPartName().getName()));
		System.out.println(imgPart.getInputStream());

		System.out.println("--------------");

		NamedNodeMap binAttrs = binNode.getAttributes();
		// 公式二进制文件在Word中的ID
		String binRid = binAttrs.getNamedItem("r:id").getNodeValue();
		// 获取二进制文件
		PackagePart binPart = word.getPartById(binRid);
		System.out.println("二进制文件名称：".concat(binPart.getPartName().getName()));
		System.out.println(binPart.getInputStream());

		InputStream in = binPart.getInputStream();
		byte[] bytes = IOUtils.toByteArray(in);
		String base64 = Base64.getEncoder().encodeToString(bytes);

		return "{公式#}";
	}
	private String getText(Node runNode) {
		Node textNode = getChildNode(runNode, "w:t");
		if (textNode == null) {
			return "";
		}
		return textNode.getFirstChild().getNodeValue();
	}
	private Node getChildNode(Node node, String nodeName) {
		if (!node.hasChildNodes()) {
			return null;
		}
		NodeList childNodes = node.getChildNodes();
		for (int i = 0; i < childNodes.getLength(); i++) {
			Node childNode = childNodes.item(i);
			if (nodeName.equals(childNode.getNodeName())) {
				return childNode;
			}
			childNode = getChildNode(childNode, nodeName);
			if (childNode != null) {
				return childNode;
			}
		}
		return null;
	}
	/**
	 * 读取word中的文本内容（段落、表格、图片分开处理）转HTML docx后缀名的Word
	 * @param
	 * @throws IOException
	 */
	public JSONObject readWordImgToHtml(XWPFDocument document,ImportRecordEntity ire,String collegeId,Long majorId,String gradeYear,String grade,String categoryId,
										String testPhase,String semester,String lg,String testType,String paperType,String studentType,String howlong,HashMap<String, ChapterEntity>  chapterMap, SysUserEntity me) throws Exception {
		JSONObject res = new JSONObject();
		res.put("code",1);
		res.put("msg","导入异常");
		try {
			// 获取word中的所有段落与表格
			List<IBodyElement> elements = document.getBodyElements();
			HashMap<String,Integer> questionTypeMap = new HashMap<>();
			questionTypeMap.put("[单选题]",1);
			questionTypeMap.put("[多选题]",2);
			questionTypeMap.put("[判断题]",3);
			questionTypeMap.put("[简答题]",4);
			questionTypeMap.put("[计算分析题]",5);
			int questionType = -1;
			StringBuffer buf = new StringBuffer();
			LibQuestionEntity libq = null;
			LibChoiceEntity libc = null;
			List<LibChoiceEntity> libcs = null;
			int orderno = 1;
			int n = 0;
			String beforeTxt = "";
;
			for (int i=0;i<elements.size();i++) {
				IBodyElement element = elements.get(i);
				// 段落
				if (element instanceof XWPFParagraph) {
					XWPFParagraph paragraph = (XWPFParagraph) element;
					String text = paragraph.getParagraphText().trim();
					String questionText = jiexiRun(paragraph,elements,i);
					if(beforeTxt.indexOf(questionText)!=-1){//判断是否重复
						continue;
					}
					beforeTxt = questionText;
					if(text.startsWith("[单选题]")||text.startsWith("[多选题]")||text.startsWith("[判断题]")||
							text.startsWith("[简答题]")||text.startsWith("[计算分析题]")){
						n++;
						libq = newQuestionEntity(ire);
						libq.setOrderno(orderno++);
						String pefixText = StringUtils.substring(text,0,5);

						if(!pefixText.endsWith("]")){
							pefixText = StringUtils.substring(text,0,7);
							questionText = StringUtils.substring(questionText,7);
						}else{
							questionText = StringUtils.substring(questionText,5);
						}
						questionType = questionTypeMap.get(pefixText);
						libq.setQuestionType(questionType);

						libq.setText(questionText);
					}else if(text.startsWith("A.")||text.startsWith("B.")||text.startsWith("C.")||text.startsWith("D.")||text.startsWith("E.")||text.startsWith("F.")
							||text.startsWith("G.")||text.startsWith("H.")||text.startsWith("A．")||text.startsWith("B．")||text.startsWith("C．")
							||text.startsWith("D．")||text.startsWith("E．")||text.startsWith("F．")
							||text.startsWith("G．")||text.startsWith("H．")){
						if(text.startsWith("A.")||text.startsWith("A．")){
							libcs = new ArrayList<>();
						}
						libc = newChoiceEntity(ire);
						libc.setIndexLetter(text.substring(0,1));
						if(libq==null){
							res.put("code",1);
							res.put("msg","第"+(n)+"题，请检查文件格式是否正确");
							System.out.println("res = " + res);
							return res;
						}

						libc.setLibQuestionId(libq.getId());
						libc.setText(questionText.substring(2).trim());
						libChoiceService.save(libc);
						libcs.add(libc);
					}else if(text.startsWith("答案：")||text.startsWith("答案:")){
						String answerTxt = questionText.substring(3).trim();
						if(answerTxt.length()>=1){
							if(questionType<=3){//选择题、判断题
								char[] letterArr = answerTxt.toCharArray();
								for (char c : letterArr) {
									for (LibChoiceEntity libChoiceEntity : libcs) {
										if(libChoiceEntity.getIndexLetter().equals(c+"")){
											libChoiceEntity.setRight(1);
											libChoiceService.save(libChoiceEntity);
										}
									}
								}
							}else{
								if(questionType>=4){
									libq.setAnswerText(answerTxt);
								}
								//把小题放在选项中
								if(libc!=null){
									libc.setAnswerText(answerTxt);
									libChoiceService.save(libc);

								}

							}
						}
					}else if(text.startsWith("解析：")||text.startsWith("解析:")){
						libq.setAnalysis(questionText.substring(3).trim());

					}else if(text.startsWith("章节：")||text.startsWith("章节:")){
						String zjText = StringUtils.deleteWhitespace(text.substring(3).trim());
						ChapterEntity chapterEntity = chapterMap.get(zjText);
						if(chapterEntity==null){
							res.put("code",1);
							res.put("msg","第"+(n)+"题，章节不正确（"+zjText+"）");
							return res;
						}
						if(libq!=null&&!libq.getText().isEmpty()){
							libq.setPianId(chapterEntity.getPianId());
							libq.setChapterId(chapterEntity.getId());
//							libq.setCategoryId(chapterEntity.getCategoryId());
							libq.setCreateTime(LocalDateTime.now());
							libq.setCreateUserId(me.getId());
							libq.setMajorId(majorId + "");
							libq.setCollegeId(collegeId);

							libq.setTestType(StringUtils.isEmpty(testType)?null:Integer.valueOf(testType));
							libq.setPaperType(StringUtils.isEmpty(paperType)?null:Integer.valueOf(paperType));
							libq.setStudentType(StringUtils.isEmpty(studentType)?null:Integer.valueOf(studentType));
							libq.setSemester(StringUtils.isEmpty(semester)?null:Integer.valueOf(semester));
							libq.setLg(StringUtils.isEmpty(lg)?null:Integer.valueOf(lg));
							libq.setGrade(StringUtils.isEmpty(grade)?null:grade);
							libq.setGradeYear(gradeYear);
							libq.setCategoryId(categoryId);
							libq.setTestPhase(StringUtils.isEmpty(testPhase)?null:Integer.valueOf(testPhase));
							@NotNull Result<Record1<Integer>> result = dsl.select(LIBQUESTIONTB.CODE).from(LIBQUESTIONTB).fetch();
							if(result.size()==0){
								libq.setCode(1);
							}else{
								Set<String> codeSet = new HashSet<>();
								for (Record1<Integer> rd : result) {
									codeSet.add(rd.get(0,String.class));
								}
								int code = 2;
								while(true){
									if(!codeSet.contains(code+"")){
										break;
									}
									code++;
								}
								libq.setCode(code);
							}

							libQuestionService.save(libq);
							libq = null;
						}
						buf = new StringBuffer();
					}
//					else{//论述题的小题
//						if(text.length()==0){
//							continue;
//						}
//						if(libq==null||libq.getQuestionType()<4){
//							continue;
//						}
//						if((text.indexOf("(")==0&&text.indexOf(")")<=3)||(text.indexOf("（")==0&&text.indexOf("）")<=3)){
//							String libqId = libq.getId();
//							libc = newChoiceEntity(ire);
//							libc.setLibQuestionId(libqId);
//							int startIndex = 0;
//							if(text.indexOf(")")>0){
//								startIndex = text.indexOf(")") + 1;
//							}else {
//								startIndex = text.indexOf("）") + 1;
//							}
//							libc.setIndexLetter(text.substring(1,startIndex-1));
//							libc.setText(questionText.substring(startIndex));
//							libChoiceService.save(libc);
//						}
//
//					}
				}else if (element instanceof XWPFTable) {
					// 表格
					XWPFTable tablex = (XWPFTable) element;
					String table = getTabelHtmlText(tablex);
					buf.append(table);
				}else{
					System.out.println("这是什么");
				}
			}
		}catch (Exception e) {
			res.put("msg","后台异常，导入失败");
			res.put("code","1");
			e.printStackTrace();
			return res;
		}finally{
			document.close();
		}
		res.put("msg","导入成功");
		res.put("code","0");

		return res;
	}
	private LibQuestionEntity newQuestionEntity(ImportRecordEntity ire){
		LibQuestionEntity libq = new LibQuestionEntity();//新建题干对象
		libq.setRecordId(ire.getId());
		libq.setId(Helper.getSnowId()+"");
		libq.setDelFlag(-1);
		libq.setIgnoreRepeat(1);
		libq.setCreateTime(LocalDateTime.now());
		return libq;
	}
	private LibChoiceEntity newChoiceEntity(ImportRecordEntity ire){
		LibChoiceEntity libc = new LibChoiceEntity();//新建题干对象
		libc.setRecordId(ire.getId());
		libc.setLibId(ire.getLibId());
		libc.setCreateTime(LocalDateTime.now());
		libc.setDelFlag(-1);
		libc.setRight(2);
		return libc;
	}

	/**
	 * 字节流图片上传
	 * @param data:图片字节流
	 * @param fileName:图片名称
	 */
	public static String getImageUrl(byte[] data,String fileName) throws Exception{
		String imgUrl="";
		Long res =new Date().getTime();
		//设置文件存储路径，可以存放在你想要指定的路径里面
		String rootPath="D:/eqfile/word/" + LocalDate.now().getYear() + "/";
        // 新文件名
        String newFileName =res + fileName.substring(fileName.lastIndexOf("."));
		//新文件
        File newFile=new File(rootPath + "/" + newFileName);
        //判断文件目录是否存在
        if(!newFile.getParentFile().exists()){
        	//如果目标文件所在的目录不存在，则创建父目录
        	newFile.getParentFile().mkdirs();
        }
        
        //-------把图片文件写入磁盘 start ----------------
        FileOutputStream fos = new FileOutputStream(newFile);
        fos.write(data);
        fos.close();
        //-------把图片文件写入磁盘 end ----------------
        //服务器图片地址
        String baseURL = "word/" + LocalDate.now().getYear() + "/";
        imgUrl=baseURL+newFileName;
        
		return imgUrl;
	}
//	private String jiexiRun(XWPFParagraph paragraph,List<IBodyElement> elements,int curNum) throws Exception {
//
//		List<XWPFRun> runs = paragraph.getRuns();
//
//		StringBuilder buf = new StringBuilder();
//		List<CTOMath> mathList = paragraph.getCTP().getOMathList();
//		for (CTOMath ctoMath : mathList) {
//			Document doc = DocumentHelper.parseText(ctoMath.xmlText());
//			Element rootElement = doc.getRootElement();
//			org.dom4j.Node meNode = rootElement.selectSingleNode("m:e");
//			org.dom4j.Node mrNode = meNode.selectSingleNode("m:r");
//			org.dom4j.Node mtNode = mrNode.selectSingleNode("m:t");
//			buf.append(mtNode.getText());
//
//		}
//		for (XWPFRun run : runs) {
//
//			List<CTSym> sylist = run.getCTR().getSymList();
//			if(sylist.size()>0){
//				for (CTSym ctSym : sylist) {
//					Document doc = DocumentHelper.parseText(ctSym.xmlText());
//					Element rootElement = doc.getRootElement();
//					String symbol = rootElement.attributeValue("char");
//					Result<Record1<Object>> symbolList = dsl.select(field("value")).from(table("symbol")).where(field("code").eq(symbol)).fetch();
//					buf.append(symbolList.size()==0?"":symbolList.get(0).get(0));
//				}
//			}
//			List<XWPFPicture> pics = run.getEmbeddedPictures();
//			if(pics.size()>0){
//				for (XWPFPicture pic : pics) {
//					XWPFPictureData pdata = pic.getPictureData();
//					double width = pic.getWidth();
//					byte[] data = pdata.getData();
//					String imgUrl = getImageUrl(data, "n.png");
//					buf.append("<img alt='' width='" + width + "' src='" + imgUrl + "'/>");
//				}
//			}
//			StringBuilder buf2 = getDirectionString(run);
//			buf.append(buf2);
//		}
//		System.out.println(buf);
//		for (int i=0;i<elements.size();i++) {
//			if(i<=curNum){
//				continue;
//			}
//			IBodyElement element = elements.get(i);
//			if(element instanceof XWPFParagraph){
//
//				XWPFParagraph paragraph1 = (XWPFParagraph)element;
//				String text = paragraph1.getText();//.replace("\n","");
//				if(!text.trim().isEmpty()){
//					IBodyElement element2 = elements.get(i-1);
//					if(!(element2 instanceof XWPFTable)){
//						buf.append("<br>");
//					}
//				}
//				if(text.startsWith("[单选题]")||text.startsWith("[多选题]")||text.startsWith("[判断题]")||
//						text.startsWith("[简答题]")||text.startsWith("[论述题]")||text.startsWith("A.")||text.startsWith("B.")||text.startsWith("C.")||text.startsWith("D.")||text.startsWith("E.")||text.startsWith("F.")
//						||text.startsWith("G.")||text.startsWith("H.")||text.startsWith("A．")||text.startsWith("B．")||text.startsWith("C．")
//						||text.startsWith("D．")||text.startsWith("E．")||text.startsWith("F．")
//						||text.startsWith("G．")||text.startsWith("H．")|text.startsWith("答案：")||text.startsWith("答案:")||text.startsWith("解析：")||text.startsWith("解析:")
//						||text.startsWith("章节：")||text.startsWith("章节:")){
//					break;
//				}
//				List<XWPFRun> runs1 = paragraph1.getRuns();
//				for (XWPFRun run1 : runs1) {
//					List<XWPFPicture> pics = run1.getEmbeddedPictures();
//					if(pics.size()>0){
//						if(i==(curNum+1)){
//							buf.append("<br>");
//						}
//						for (XWPFPicture pic : pics) {
//							XWPFPictureData pdata = pic.getPictureData();
//							double width = pic.getWidth();
//							byte[] data = pdata.getData();
//							String imgUrl = getImageUrl(data, "n.png");
//							buf.append("<img alt='' width='" + width + "' src='" + imgUrl + "'/>");
//						}
//					}
//					List<CTSym> sylist = run1.getCTR().getSymList();
//					if(sylist.size()>0){
//						for (CTSym ctSym : sylist) {
//							org.openxmlformats.schemas.wordprocessingml.x2006.main.STShortHexNumber symbol = ctSym.xgetChar();
//							String symbolText = symbol.getStringValue();
//							Result<Record1<Object>> symbolList = dsl.select(field("value")).from(table("symbol")).where(field("code").eq(symbolText)).fetch();
//							buf.append(symbolList.size()==0?"":symbolList.get(0).get(0));
//						}
//					}else{
//
//						StringBuilder buf2 = getDirectionString(run1);
//						buf.append(buf2);
//					}
//				}
//			}else if(element instanceof XWPFTable){
//				XWPFTable table = (XWPFTable)element;
//				String tablestr = getTabelHtmlText(table);
//				buf.append(tablestr);
//			}
//		}
//		return buf.toString();
//	}
	private String jiexiRun(XWPFParagraph paragraph,List<IBodyElement> elements,int curNum) throws Exception {
		StringBuilder buf = new StringBuilder();
		Node dom = paragraph.getCTP().getDomNode();
//		System.out.println("paragraph.getCTP() = " + paragraph.getCTP());
		NodeList kids = dom.getChildNodes();
		for(int i=0;i<kids.getLength();i++){
			Node node = kids.item(i);
			if(node.getNodeName().equals("w:r")){
				jiexiWr(node,buf,paragraph);
			}else if(node.getNodeName().equals("m:oMath")){
				Node supNode = node.getFirstChild();
				NodeList mKids = supNode.getChildNodes();
				for (int j=0;j<mKids.getLength();j++){
					Node meNode = mKids.item(j);
					boolean fill = false;
					if(meNode.getNodeName().equals("m:e")){
						NodeList meKids = meNode.getChildNodes();
						Node meNode2 = null,accNode = null;
						for(int k=0;k<meKids.getLength();k++){
							Node meKid = meKids.item(k);
							if(meKid.getNodeName().equals("m:e")){
								meNode2 = meKid;
							}
							if(meKid.getNodeName().equals("m:acc")){
								accNode = meKid;
							}
						}
						if(meNode2==null){
							if(accNode!=null){
								NodeList accKids = accNode.getChildNodes();
								for(int k=0;k<accKids.getLength();k++){
									Node accKid = accKids.item(k);
									if(accKid.getNodeName().equals("m:e")){
										jiexiMathWr(accNode,accKid,buf);
										fill = true;
									}
								}
							}
						}
						if(!fill){
							jiexiMathWr(null,meNode,buf);
						}

					}else if(meNode.getNodeName().equals("m:sup")){
						jiexiMathSup(meNode,buf);
					}else if(meNode.getNodeName().equals("m:sub")){
						jiexiMathSub(meNode,buf);
					}
				}
			}
		}
		List<XWPFRun> runs = paragraph.getRuns();
		for (XWPFRun run : runs) {
			List<XWPFPicture> pics = run.getEmbeddedPictures();
			for (XWPFPicture pic : pics) {
				XWPFPictureData pdata = pic.getPictureData();
				double width = pic.getWidth();
				byte[] data = pdata.getData();
				String imgUrl = getImageUrl(data, "n.png");
				String str = buf.toString();
				int index = str.indexOf("{pic}");
				String str1 = StringUtils.substring(str,0,index);
				String str2 = StringUtils.substring(str,index+5);
				buf = new StringBuilder(str1 + "<img alt='' width='" + width + "\"' src='" + imgUrl + "'/>" + str2);
			}
		}

		for (int k=0;k<elements.size();k++) {
			if (k <= curNum) {
				continue;
			}
			IBodyElement element = elements.get(k);
			if (element instanceof XWPFParagraph) {
				XWPFParagraph paragraph1 = (XWPFParagraph)element;
				String text = paragraph1.getText();//.replace("\n","");
				if(!text.trim().isEmpty()){
					IBodyElement element2 = elements.get(k-1);
					if(!(element2 instanceof XWPFTable)){
						buf.append("<br/>");
					}
				}
				if(text.startsWith("[单选题]")||text.startsWith("[多选题]")||text.startsWith("[判断题]")||
						text.startsWith("[简答题]")||text.startsWith("[计算分析题]")||text.startsWith("A.")||text.startsWith("B.")||text.startsWith("C.")||text.startsWith("D.")||text.startsWith("E.")||text.startsWith("F.")
						||text.startsWith("G.")||text.startsWith("H.")||text.startsWith("A．")||text.startsWith("B．")||text.startsWith("C．")
						||text.startsWith("D．")||text.startsWith("E．")||text.startsWith("F．")
						||text.startsWith("G．")||text.startsWith("H．")|text.startsWith("答案：")||text.startsWith("答案:")||text.startsWith("解析：")||text.startsWith("解析:")
						||text.startsWith("章节：")||text.startsWith("章节:")){
					break;
				}
				Node dom1 = paragraph1.getCTP().getDomNode();
				NodeList kids1 = dom1.getChildNodes();
				for(int i=0;i<kids1.getLength();i++){
					Node node = kids1.item(i);
					if(node.getNodeName().equals("w:r")){
						jiexiWr(node,buf,paragraph);
					}else if(node.getNodeName().equals("m:oMath")){
						Node supNode = node.getFirstChild();
						NodeList mKids = supNode.getChildNodes();
						boolean fill = false;
						for (int j=0;j<mKids.getLength();j++){
							Node meNode = mKids.item(j);
							if(meNode.getNodeName().equals("m:e")){
								NodeList meKids = meNode.getChildNodes();
								Node meNode2 = null,accNode = null;
								for(int a=0;a<meKids.getLength();a++){
									Node meKid = meKids.item(a);
									if(meKid.getNodeName().equals("m:e")){
										meNode2 = meKid;
									}
									if(meKid.getNodeName().equals("m:acc")){
										accNode = meKid;
									}
								}
								if(meNode2==null){
									if(accNode!=null){
										NodeList accKids = accNode.getChildNodes();
										for(int b=0;b<accKids.getLength();b++){
											Node accKid = accKids.item(b);
											if(accKid.getNodeName().equals("m:e")){
												jiexiMathWr(accNode,accKid,buf);
												fill = true;
											}
										}
									}
								}
								if(!fill){
									jiexiMathWr(null,meNode,buf);
								}
							}else if(meNode.getNodeName().equals("m:sup")){
								jiexiMathSup(meNode,buf);
							}else if(meNode.getNodeName().equals("m:sub")){
								jiexiMathSub(meNode,buf);
							}
						}
					}
				}
				List<XWPFRun> runs1 = paragraph1.getRuns();
				for (XWPFRun run : runs1) {
					List<XWPFPicture> pics = run.getEmbeddedPictures();
					for (XWPFPicture pic : pics) {
						XWPFPictureData pdata = pic.getPictureData();
						double width = pic.getWidth();
						byte[] data = pdata.getData();
						String imgUrl = getImageUrl(data, "n.png");
						String str = buf.toString();
						int index = str.indexOf("{pic}");
						String str1 = StringUtils.substring(str,0,index);
						String str2 = StringUtils.substring(str,index+5);
						if(width>180){
							buf = new StringBuilder(str1 + "<br/><img alt='' width='" + width + "\"' src='" + imgUrl + "'/>" + str2);
						}else {
							buf = new StringBuilder(str1 + "<img alt='' width='" + width + "\"' src='" + imgUrl + "'/>" + str2);
						}

					}
				}
			}else if(element instanceof XWPFTable){
				// 表格
				XWPFTable tablex = (XWPFTable) element;
				String table = getTabelHtmlText(tablex);
				buf.append(table);
			}
		}
		return buf.toString();
	}
	private void jiexiWr(Node node,StringBuilder buf,XWPFParagraph paragraph){

		Node wtNode = node.getLastChild();
		if(wtNode.getNodeName().equals("w:t")){
			Node styleNode = null;
			NodeList nodeKids = node.getChildNodes();
			for(int i=0;i<nodeKids.getLength();i++){
				styleNode = nodeKids.item(i);
				if(styleNode.getNodeName().equals("w:rPr")){
					break;
				}
			}
			NodeList skids = styleNode.getChildNodes();
			String style = "";
			boolean sup = false,sub = false;
			for(int j = 0; j < skids.getLength(); j++){
				Node skid = skids.item(j);
				if(skid.getNodeName().equals("w:b")){
					if(style.length()==0){
						style = "<span style='";
					}
					style += "font-weight:bolder;";
				}
				if(skid.getNodeName().equals("w:strike")){
					if(style.length()==0){
						style = "<span style='";
					}
					style += "text-decoration: line-through;";
				}
				if(skid.getNodeName().equals("w:i")){
					if(style.length()==0){
						style = "<span style='";
					}
					style += "font-style:italic;";
				}

				if(skid.getNodeName().equals("w:vertAlign")){
					NamedNodeMap atts = skid.getAttributes();
					for(int n=0;n<atts.getLength();n++){
						if(atts.item(n).getNodeValue().equals("subscript")){
							sub = true;
						}else if(atts.item(n).getNodeValue().equals("superscript")){
							sup = true;
						}

					}
				}
			}
			if(style.length()>0){
				style += "'>";
			}
			String v = wtNode.getFirstChild().getNodeValue();
			if(sub){
				v = "<sub>" + wtNode.getFirstChild().getNodeValue() + "</sub>";
			}else if(sup){
				v = "<sup>" + wtNode.getFirstChild().getNodeValue() + "</sup>";
			}
			buf.append(style + v + ((style.length()==0)?"":"</span>"));
		}else if(wtNode.getNodeName().equals("w:drawing")){
			buf.append("{pic}");
		}else if(wtNode.getNodeName().equals("w:sym")){
			Node styleNode = null;
			NodeList nodeKids = node.getChildNodes();
			for(int i=0;i<nodeKids.getLength();i++){
				styleNode = nodeKids.item(i);
				if(styleNode.getNodeName().equals("w:rPr")){
					break;
				}
			}
			NodeList skids = styleNode.getChildNodes();
			String style = "";
			for(int n=0;n<skids.getLength();n++){
				Node skid = skids.item(n);
				if(skid.getNodeName().equals("w:b")){
					if(style.length()==0){
						style = "<span style='";
					}
					style += "font-weight:bolder;";
				}
				if(skid.getNodeName().equals("w:i")){
					if(style.length()==0){
						style = "<span style='";
					}
					style += "font-style:italic;";
				}
			}
			if(style.length()>0){
				style += "'>";
			}
			NamedNodeMap attList = wtNode.getAttributes();
			for(int n=0;n<attList.getLength();n++){
				Node att = attList.item(n);
				if(att.getNodeName().equals("w:char")){
					String symbol = att.getNodeValue();
					Result<Record1<Object>> symbolList = dsl.select(field("value")).from(table("symbol")).where(field("code").eq(symbol)).fetch();
					Object v = symbolList.size() == 0 ? "" : symbolList.get(0).get(0);
					buf.append(style + v + ((style.length()==0)?"":"</span>"));
				}
			}
		}
	}

	private void jiexiMathWr(Node accNode,Node node,StringBuilder buf){
		Node mrNode = node.getFirstChild();
		Node wtNode = mrNode.getLastChild();
		Node styleNode = node.getLastChild().getFirstChild();
		NodeList skids = styleNode.getChildNodes();
		String style = "";
		for(int j = 0; j < skids.getLength(); j++){
			Node skid = skids.item(j);
			if(skid.getNodeName().equals("w:b")){
				if(style.length()==0){
					style = "<span style='";
				}
				style += "font-weight:bolder;";
			}
			if(skid.getNodeName().equals("w:i")){
				if(style.length()==0){
					style = "<span style='";
				}
				style += "font-style:italic;";
			}
		}
		if(accNode!=null){
			NodeList accKids = accNode.getChildNodes();
			for(int k=0;k<accKids.getLength();k++){
				Node kid = accKids.item(k);
				if(kid.getNodeName().equals("m:accPr")){
					style += "text-decoration:overline;";
				}
			}
		}
		if(style.length()>0){
			style += "'>";
		}
		if(wtNode.getNodeName().equals("m:t")){

			buf.append(style + wtNode.getFirstChild().getNodeValue() + ((style.length()==0)?"":"</span>"));
		}
	}
	private void jiexiMathSup(Node node,StringBuilder buf){
		Node mrNode = node.getFirstChild();
		Node wtNode = mrNode.getLastChild();
		Node styleNode = node.getLastChild().getFirstChild();
		NodeList skids = styleNode.getChildNodes();
		String style = "";
		for(int j = 0; j < skids.getLength(); j++){
			Node skid = skids.item(j);
			if(skid.getNodeName().equals("w:b")){
				if(style.length()==0){
					style = "<span style='";
				}
				style += "font-weight:bolder;";
			}
			if(skid.getNodeName().equals("w:i")){
				if(style.length()==0){
					style = "<span style='";
				}
				style += "font-style:italic;";
			}
		}
		if(style.length()>0){
			style += "'>";
		}
		if(wtNode.getNodeName().equals("m:t")){
			buf.append(style + "<sup>" + wtNode.getFirstChild().getNodeValue() +"</sup>"+ ((style.length()==0)?"":"</span>"));
		}
	}
	private void jiexiMathSub(Node node,StringBuilder buf){
		Node mrNode = node.getFirstChild();
		Node wtNode = mrNode.getLastChild();
		Node styleNode = node.getLastChild().getFirstChild();
		NodeList skids = styleNode.getChildNodes();
		String style = "";
		for(int j = 0; j < skids.getLength(); j++){
			Node skid = skids.item(j);
			if(skid.getNodeName().equals("w:b")){
				if(style.length()==0){
					style = "<span style='";
				}
				style += "font-weight:bolder;";
			}
			if(skid.getNodeName().equals("w:i")){
				if(style.length()==0){
					style = "<span style='";
				}
				style += "font-style:italic;";
			}
		}
		if(style.length()>0){
			style += "'>";
		}
		if(wtNode.getNodeName().equals("m:t")){
			buf.append(style + "<sub>" + wtNode.getFirstChild().getNodeValue() +"</sub>"+ ((style.length()==0)?"":"</span>"));
		}
	}
	@NotNull
	private StringBuilder getDirectionString(XWPFRun run) {

		StringBuilder buf2 = new StringBuilder();
		if(run.isBold()){
			if(buf2.length()==0) {
				buf2.append("<span style='font-weight:bolder;");
			}
		}
		if(run.isItalic()){
			if(buf2.length()==0) {
				buf2.append("<span style='font-style:italic;");
			}
		}
		if (buf2.length()>0&&buf2.toString().startsWith("<span ")){
			buf2.append("'>");
		}
		String runText = run.getText(0);
		runText = runText==null?"":runText.replace("\n","");
		if(isSubscript(run)){
			buf2.append("<sub>" + runText + "</sub>");
		}else if(isSuperscript(run)){
			buf2.append("<sup>" + runText + "</sup>");
		}else {
			buf2.append(runText);
		}
		if(buf2.indexOf("<span ")>-1){
			buf2.append("</span>");
		}
		return buf2;
	}

	public static boolean isSubscript(XWPFRun run){
		boolean flag=false;
		if(run.getCTR()!=null){
			if(run.getCTR().getRPr()!=null){
				if(run.getCTR().getRPr().getVertAlign()!=null){
					if(run.getCTR().getRPr().getVertAlign().getVal().toString().toLowerCase().equals("subscript")){
						flag=true;
					}
				}
			}
		}
		return flag;
	}
	public static boolean isUnder(XWPFRun run){
		boolean flag=false;
		if(run.getCTR()!=null){
			if(run.getCTR().getRPr()!=null){
				if(run.getCTR().getRPr().getU()!=null){
					if(run.getCTR().getRPr().getU().getVal().toString().toLowerCase().equals("single")){
						flag=true;
					}
				}
			}
		}
		return flag;

	}
	public static boolean isSuperscript(XWPFRun run){
		boolean flag=false;
		if(run.getCTR()!=null){
			if(run.getCTR().getRPr()!=null){
				if(run.getCTR().getRPr().getVertAlign()!=null){
					if(run.getCTR().getRPr().getVertAlign().getVal().toString().toLowerCase().equals("superscript")){
						flag=true;
					}
				}
			}
		}
		return flag;
	}
}
